
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.IO;
using System.Security.Permissions;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Swaf.Gui;

namespace Swaf.Gui.AspNet2
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [Themeable(true)]
    public class BasicPaginationDisplay : Swaf.Gui.AspNet2.UserControl, IPaginationDisplay
    {
        protected int m_totalElements = 0;
        protected int m_elementsPerPage = 0;
        protected int m_currentPage = -1;
        protected int m_groupSize = 10;

        protected string m_prefixInfoHtml = "Pages: ";
        protected string m_prevGroupHtml = "Prev";
        protected string m_nextGroupHtml = "Next";
        protected string m_pagePrefixHtml = "&nbsp[";
        protected string m_pagePostfixHtml = "]";
        protected string m_pageCountSummary = "Total Pages: ";

        protected string m_prefixClass = "";
        protected string m_groupingClass = "";
        protected string m_pagesClass = "";
        protected string m_currentPageClass = "";
        protected string m_summaryClass = "";

		protected bool m_createActiveOnLoad = true;

        [Category("Appearance")]
        public string PrefixClass { get { return (string)getOffline("m_prefixClass"); } set { putOffline("m_prefixClass", value); } }
        [Category("Appearance")]
        public string GroupingClass { get { return (string)getOffline("m_groupingClass"); } set { putOffline("m_groupingClass", value); } }
        [Category("Appearance")]
        public string PagesClass { get { return (string)getOffline("m_pagesClass"); } set { putOffline("m_pagesClass", value); } }
        [Category("Appearance")]
        public string CurrentPageClass { get { return (string)getOffline("m_currentPageClass"); } set { putOffline("m_currentPageClass", value); } }
        [Category("Appearance")]
        public string SummaryClass { get { return (string)getOffline("m_summaryClass"); } set { putOffline("m_summaryClass", value); } }

        [Category("Appearance")]
        public string PrefixHtml { get { return (string)getOffline("m_pagePrefixHtml"); } set { putOffline("m_pagePrefixHtml", value); } }
        [Category("Appearance")]
        public string PostfixHtml { get { return (string)getOffline("m_pagePostfixHtml"); } set { putOffline("m_pagePostfixHtml", value); } }
        [Category("Appearance")]
        public string PrevGroupHtml { get { return (string)getOffline("m_prevGroupHtml"); } set { putOffline("m_prevGroupHtml", value); } }
        [Category("Appearance")]
        public string NextGroupHtml { get { return (string)getOffline("m_nextGroupHtml"); } set { putOffline("m_nextGroupHtml", value); } }

		protected BizProcWidgetType m_procWidgetType = BizProcWidgetType.pager;
		public BizProcWidgetType BizProcType { get { return m_procWidgetType; } set { m_procWidgetType = value; } }


		public BasicPaginationDisplay() : base() { }
		public BasicPaginationDisplay(ActiveWidget widget) : base(widget) { }


		protected override void OnLoad(EventArgs e)
		{
			if (m_createActiveOnLoad)
			{
				WidgetOfflineState offlineState = State;
				ActiveWidget act = new ActiveWidget(this, BPC, offlineState);
				act.CreatedFromPage = Page.GetType().Name.CompareTo("ajaxrequesthandler_aspx") != 0;
				act.State.BizProcWidgetType = BizProcWidgetType.pager;
				BPC.defineActiveWidget(act);
				PrefixClass = PrefixClass; GroupingClass = GroupingClass; PagesClass = PagesClass; CurrentPageClass = CurrentPageClass; SummaryClass = SummaryClass;
				PrefixHtml = PrefixHtml; PostfixHtml = PostfixHtml; PrevGroupHtml = PrevGroupHtml; NextGroupHtml = NextGroupHtml;
			}
			setupState();
			base.OnLoad(e);
		}

		protected void setupState()
        {
			if (State.State["CP"] != null)
				m_currentPage = (int)State.State["CP"];
            else if (m_currentPage == -1)
                m_currentPage = 0;

            if (Page.Request.Form["__EVENTTARGET"] == this.UniqueID)
            {
                string action = Page.Request.Form["__EVENTARGUMENT"];
				setupCurrentPage(action);
            }
        }

		protected virtual void setupCurrentPage(string action)
		{
			int newPage = m_currentPage;
			if (action == "NG")
				newPage = (calcGroup(m_currentPage) + 1) * m_groupSize;
			else if (action == "PG")
				newPage = (calcGroup(m_currentPage) - 1) * m_groupSize;
			else
				Int32.TryParse(action, out newPage);
			if (newPage < 0)
				newPage = 0;
			ActiveBizProc bizproc = BPC.getActiveBizProc(State.ParentBizProcIds[0]);
			bizproc.BizProc.CurrentPage = m_currentPage = newPage;
			State.State["CP"] = m_currentPage;
		}

        protected override void Render(HtmlTextWriter w)
        {
			renderIntoWriter(w);
        }

		protected virtual void renderIntoWriter(TextWriter w)
		{
			bool drawGroupMove = NumPages > GroupSize;

			w.Write("<div id='{0}' class='{1}'>", ClientID, CssClass);
			if (m_prefixInfoHtml != null && m_prefixInfoHtml != "")
				w.Write("<span class=\"{0}\">{1}</span>", PrefixClass, m_prefixInfoHtml);

			if (drawGroupMove)
				w.Write("<span onclick=\"{0}\" class=\"{1} PrevGroup\">{2}</span>",
					genPostBack("PG"), GroupingClass, PrevGroupHtml);

			int firstNum = (int)(calcGroup(m_currentPage) * GroupSize) + 1;
			for (int pos = firstNum; pos < firstNum + GroupSize && pos <= NumPages; ++pos)
				w.Write("<span onclick=\"{0}\" class=\"{1}\">{2}{3}{4}</span>",
					genPostBack((pos - 1).ToString()), pos == m_currentPage + 1 ? CurrentPageClass : PagesClass,
					PrefixHtml, pos.ToString(), PostfixHtml);

			if (drawGroupMove)
			{
                w.Write("<span style='cursor:pointer' onclick=\"{0}\" class=\"{1} NextGroup\">{2}</span>",
					genPostBack("NG"), GroupingClass, NextGroupHtml);

				w.Write("<span class=\"{0}\">{1} {2}</span>", SummaryClass, m_pageCountSummary, NumPages);
			}

			w.Write("</div>");
		}

        protected virtual string genPostBack(string pInfo)
        {
            StringBuilder buff = new StringBuilder(100);
            buff.Append("__doPostBack('").Append(this.UniqueID).Append("','").Append(pInfo).Append("')");
            return buff.ToString();
        }
        public int GroupSize { get { return m_groupSize; } set { m_groupSize = value; } }

        protected int calcGroup(int pageNum)
        {
            int g = pageNum==0?0:(int)(pageNum / GroupSize);
            return g;
        }
        protected int NumGroups { get { return calcTotal(NumPages, GroupSize); } }
        protected int NumPages {get{return calcTotal(m_totalElements, m_elementsPerPage);}}

        int calcTotal(int totalItems, int itemsPer)
        {
            if (itemsPer == -1 || itemsPer == 0)
                return 1;
            else
            {
                int num = (int)(totalItems / itemsPer);
                if (totalItems % itemsPer != 0)
                    ++num;
                return num;
            }
        }

        #region IPaginationDisplay Members

        public void setupPagination(int totalElements, int elementsPerPage, int currentPage)
        {
            m_totalElements = totalElements;
            m_elementsPerPage = elementsPerPage;
			State.State["CP"] = m_currentPage = currentPage;
        }

        #endregion

        #region IWidget Members

        public string WidgetId
        {
            get { return ClientID; }
        }

        #endregion
	}
}
